package com.usian.wemedia.service.impl;

import com.alibaba.fastjson.JSON;
import com.baomidou.mybatisplus.core.conditions.query.LambdaQueryWrapper;
import com.baomidou.mybatisplus.core.metadata.IPage;
import com.baomidou.mybatisplus.core.toolkit.Wrappers;
import com.baomidou.mybatisplus.extension.plugins.pagination.Page;
import com.baomidou.mybatisplus.extension.service.impl.ServiceImpl;
import com.usian.common.exception.CatchCustomException;
import com.usian.model.common.dtos.PageResponseResult;
import com.usian.model.common.dtos.ResponseResult;
import com.usian.model.common.enums.AppHttpCodeEnum;
import com.usian.model.media.dtos.WmNewsDto;
import com.usian.model.media.dtos.WmNewsPageReqDto;
import com.usian.model.media.pojos.WmMaterial;
import com.usian.model.media.pojos.WmNews;
import com.usian.model.media.pojos.WmNewsMaterial;
import com.usian.model.media.pojos.WmUser;
import com.usian.utils.threadlocal.WmThreadLocalUtils;
import com.usian.wemedia.config.RabbitmqConfig;
import com.usian.wemedia.mapper.WmMaterialMapper;
import com.usian.wemedia.mapper.WmNewsMapper;
import com.usian.wemedia.mapper.WmNewsMaterialMapper;
import com.usian.wemedia.service.WmNewsService;
import org.apache.commons.lang3.StringUtils;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.beans.BeanUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;
import org.springframework.transaction.annotation.Transactional;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.Map;
import java.util.stream.Collectors;


@Service
public class WmNewsServiceImpl extends ServiceImpl<WmNewsMapper, WmNews> implements WmNewsService {

    @Autowired
    private WmNewsMaterialMapper wmNewsMaterialMapper;
    @Autowired
    private WmMaterialMapper wmMaterialMapper;

    /**
     * 查询所有自媒体文章
     *
     * @return
     */
    @Override
    public ResponseResult findAll(WmNewsPageReqDto dto) {
        // 判断用户是否登录
        WmUser user = WmThreadLocalUtils.getUser();
        if (user == null) {
            CatchCustomException.catchs(20001, "用户没有登录");
        }
        // 判断参数
        if (dto == null) {
            CatchCustomException.catchs(20002, "参数有误");
        }
        // 分页初始化
        dto.checkParam();
        // 封装条件
        LambdaQueryWrapper<WmNews> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        // 关键字
        lambdaQueryWrapper.like(
                StringUtils.isNoneEmpty(dto.getKeyword()),
                WmNews::getTitle, dto.getKeyword());
        // 频道ID
        lambdaQueryWrapper.eq(dto.getChannelId() != null,
                WmNews::getChannelId, dto.getChannelId()
        );
        // 状态
        lambdaQueryWrapper.eq(dto.getStatus() != null, WmNews::getStatus, dto.getStatus());
        /*
         * 区间查询
         * ge 大于等于
         * le 小于等于
         * */
        // 开始时间
        lambdaQueryWrapper.ge(dto.getBeginPubDate() != null, WmNews::getCreatedTime, dto.getBeginPubDate());
        // 结束时间
        lambdaQueryWrapper.le(dto.getEndPubDate() != null, WmNews::getCreatedTime, dto.getEndPubDate());
        /*
         * 区间查询
         * 使用Between
         * */
      /*     lambdaQueryWrapper.between(
                dto.getEndPubDate()!=null && dto.getBeginPubDate()!=null,
                WmNews::getCreatedTime,dto.getBeginPubDate(),dto.getEndPubDate()
        );*/

        // 排序：
        lambdaQueryWrapper.orderByDesc(WmNews::getCreatedTime);
        // 分页条件
        IPage<WmNews> page = this.page(new Page<>(dto.getPage(), dto.getSize()), lambdaQueryWrapper);
        PageResponseResult responseResult = new PageResponseResult(page.getCurrent(), page.getSize(), page.getTotal());
        responseResult.setData(page.getRecords());
        return responseResult;
    }

    @Transactional
    @Override
    public ResponseResult saveNews(WmNewsDto dto, Short isSubmit) {
        //  判断参数
        if (dto == null || StringUtils.isBlank(dto.getContent())) {
            CatchCustomException.catchs(20003, "保存信息不完成，不能操作");
        }
        // 保存文章数据
        WmNews wmNews = new WmNews();
        //深克隆 -- dto 东西拿出来  --》 wmnews
        //wmNews = JSON.parseObject(JSON.toJSONString(dto),WmNews.class);
        BeanUtils.copyProperties(dto, wmNews);

        /*

         如果是-1的情况 代表需要从内容中获取数据 进行自定封面设置
         */
        if (-1 == dto.getType()) {
            wmNews.setType(null);
        }
        /*
       洗数据-- 把数组中的图片都取出来
        ["http://192.168.200.130/group1/M00/00/00/wKjIgl5swbGATaSAAAEPfZfx6Iw790.png",
         "http://192.168.200.130/group1/M00/00/00/wKjIgl5swbGATaSAAAEPfZfx6Iw790.png",
         "http://192.168.200.130/group1/M00/00/00/wKjIgl5swbGATaSAAAEPfZfx6Iw790.png"]
        */
        if (dto.getImages() != null && dto.getImages().size() > 0) {
            /*第一种方法：先去出“[]” 两端中括号
              再去除 http://192.168.211.132:8080 使用fastdfs方式 保存的图片需要这一步   oss 或kodo保存图片 忽略
         String images=dto.getImages().toString().
         replace("[","").replace("]","").
         replace("http://192.168.211.132:8080","").
         replace("","");
         保存
            wmNews.setImages(images);
            * */
            /*
             * 第二种方法
             *    把数组进行for循环 在赋值给 images
             *    对images进行 分割
             * */
            String images = "";
            for (String image : dto.getImages()) {
                images += image + ",";
            }
            wmNews.setImages(images.substring(0, images.length() - 1));

        }
        // 保存 或修改数据到数据库
        this.saveWmnews(wmNews, isSubmit);
        // 判断类型 type 0 封面类型 0：无图文章  3：单图文章  1：多图文章   -1
        // 读取文章内容
        String content = dto.getContent();
        //  转换集合
        List<Map> contentList = JSON.parseArray(content, Map.class);
        // 获取所有的素材  （图文中的图片集合）
        List<String> materials = this.upGetImagesForContentList(contentList);
        if (isSubmit == WmNews.Status.SUBMIT.getCode() && materials.size() != 0) {
            //设置内容
            saveRelativeInfoForNR(materials, wmNews);
        }
        // 2. 主图引用   中间表
        if (isSubmit == WmNews.Status.SUBMIT.getCode()) {
            // 封面与 单图 三图 无图  自动相关
            saveRelativeInfoForFM(dto, materials, wmNews);
        }
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }



    /**
     * @param materials 素材集合
     * @param wmNews    文章信息
     * @param type      0 图文引用  1 封面引用
     * @return
     */
    private void saveRelativeInfo(List<String> materials, WmNews wmNews, Short type) {
        List<String> materialIds = new ArrayList<>();
        //根据素材获取ID
        LambdaQueryWrapper<WmMaterial> lambdaQueryWrapper = new LambdaQueryWrapper<>();
        lambdaQueryWrapper.in(WmMaterial::getUrl, materials);
        lambdaQueryWrapper.eq(WmMaterial::getUserId, wmNews.getUserId());
        List<WmMaterial> list = wmMaterialMapper.selectList(lambdaQueryWrapper);
        Map<String, Integer> map = list.stream().collect(Collectors.toMap(WmMaterial::getUrl, WmMaterial::getId));
        if (list != null && list.size() > 0) {
            for (String url : materials) {
                Integer materiaId = map.get(url);
                materialIds.add(String.valueOf(materiaId));
            }
        }
        // 保存
        wmMaterialMapper.saveRelationsByContent(materialIds, wmNews.getId(), type);
    }

    /**
     * 设置内容图片与素材的关系
     */
    public void saveRelativeInfoForNR(List<String> materials, WmNews wmNews) {
        saveRelativeInfo(materials, wmNews, (short) 0);
    }

    /**
     * 设置封面图片与素材的关系
     *
     * @return
     */
    public void saveRelativeInfoForFM(WmNewsDto dto, List<String> materials, WmNews wmNews) {
        // 保存关系
        List<String> imagesList = dto.getImages();
        if (-1 == dto.getType()) { // 自动
            if (materials != null && materials.size() > 0 && materials.size() <= 2) {
                // 单图
                wmNews.setType((short) 1);
                imagesList = materials.stream().limit(1).collect(Collectors.toList());
            } else if (materials != null && materials.size() > 2) {
                //三图
                wmNews.setType((short) 3);
                imagesList = materials.stream().limit(3).collect(Collectors.toList());
            } else {
                // 无图
                wmNews.setType((short) 0);
            }
        }

        if (imagesList != null && imagesList.size() > 0) {
            String images = "";
            for (String image : imagesList) {
                images += image + ",";
            }
            if (wmNews.getImages() == null || "".equals(wmNews.getImages())) {
                wmNews.setImages(images.substring(0, images.length() - 1));
            }
            //保存素材关系
            this.saveRelativeInfo(imagesList, wmNews, (short) 1);
        }
        // 修改wmnes
        this.updateById(wmNews);
    }

    /**
     * 提取图文中的图片集合
     */
    private List<String> upGetImagesForContentList(List<Map> contentList) {
        List<String> materials = new ArrayList<>();
        contentList.stream().forEach(x -> {
            if ("image".equals(x.get("type"))) {
                materials.add((String) x.get("value"));
            }
        });
        return materials;
    }

    /*
     保存 或修改数据到数据库
    * */
    private void saveWmnews(WmNews wmNews, Short isSubmit) {
        // 用户登录
        // 获取用户信息
        WmUser user = WmThreadLocalUtils.getUser();
        if (user == null) {
            CatchCustomException.catchs(20001, "用户没有登录");
        }
        // 草稿  或者 提交
        wmNews.setStatus(isSubmit);
        if (wmNews.getId() != null) {
            // 修改
            this.updateById(wmNews);
            // 删除关联表数据  文章ID
            wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId,
                    wmNews.getId()));
        } else {
            // 添加
            wmNews.setUserId(user.getId());
            wmNews.setCreatedTime(new Date());
            if (isSubmit == 1) {
                wmNews.setSubmitedTime(new Date());
            }
            wmNews.setEnable((short) 0);
            this.save(wmNews);
        }
    }


    //根据id获取文章消息
    @Override
    public ResponseResult findWmNewsById(Integer id) {
        if (id == null) {
            CatchCustomException.catchs(20003, "文章ID不可查询");
        }
        if (WmThreadLocalUtils.getUser() == null) {
            CatchCustomException.catchs(20003, "当前用户身份有误");
        }
        WmNews wmNews = this.getOne(Wrappers.<WmNews>lambdaQuery().eq(WmNews::getId, id).eq(WmNews::getUserId, WmThreadLocalUtils.getUser().getId()));
        if (wmNews == null) {
            CatchCustomException.catchs(20003, "当前文章不可用");
        }
        //3.结果返回
        return ResponseResult.okResult(wmNews);
    }

    //删除文章

    @Transactional
    @Override
    public ResponseResult delNews(Integer id) {
        if (id == null) {
            CatchCustomException.catchs(20003, "文章ID有误");
        }
        // 状态和上架信息
        WmNews wmNews = this.getById(id);
        if (wmNews == null) {
            CatchCustomException.catchs(20003, "当前文章不可用");
        }
        if(wmNews.getStatus() == 9 && wmNews.getEnable() == 1){
            CatchCustomException.catchs(20003, "当前文章上架状态，不可删除");
        }
        removeById(wmNews.getId());
        // 删除引用信息
        wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, wmNews.getId()));
        return  ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    //上下架
    @Override
    public ResponseResult downOrUp(WmNewsDto dto) {
        if(dto == null ){
            CatchCustomException.catchs(20003, "参数不合法");
        }
        if(dto.getId() == null || dto.getEnable()==null){
            CatchCustomException.catchs(20003, "参数不合法");
        }
        if(dto.getEnable()>1 || dto.getEnable()<0){
            CatchCustomException.catchs(20003, "上下架操作失败");
        }
        //先查询
        WmNews wmNews =  this.getById(dto.getId());
        if(wmNews == null ){
            CatchCustomException.catchs(20003, "参数不合法");
        }
        if(wmNews.getStatus() != 9){
            CatchCustomException.catchs(20003, "文章尚未审核，不能进行上下架操作");
        }

        wmNews.setEnable(dto.getEnable());
        this.updateById(wmNews);
        return ResponseResult.okResult(AppHttpCodeEnum.SUCCESS);
    }

    @Autowired
    private RabbitTemplate rabbitTemplate;

    /*
    保存或者修改
   * */
    private void saveWmNews(WmNews wmNews, Short isSubmit) {
        boolean flag = true;
        // 获取用户信息
        WmUser wmUser = WmThreadLocalUtils.getUser();
        if (wmUser == null) {
            CatchCustomException.catchs(20001, "用户没有登录");
        }
        // 草稿  或者 提交
        wmNews.setStatus(isSubmit);
        if (wmNews.getId() != null) {
            //修改
            flag =  this.updateById(wmNews);
            // 删除关联表数据   文章ID
            wmNewsMaterialMapper.delete(Wrappers.<WmNewsMaterial>lambdaQuery().eq(WmNewsMaterial::getNewsId, wmNews.getId()));
        } else {
            //添加
            wmNews.setUserId(wmUser.getId());
            wmNews.setCreatedTime(new Date());
            if (isSubmit == 1) {
                wmNews.setSubmitedTime(new Date());
            }
            wmNews.setEnable((short) 0);
            flag =  this.save(wmNews);
        }
        if(isSubmit == 1 && flag){
            //发送自动审核  MQ
            rabbitTemplate.convertAndSend(RabbitmqConfig.EXCHANGE_DIRECT_WMNEWSAUTO,"wmnesauto",wmNews.getId());
        }
    }

}

